package com.sunriz.ctrl.server.driver;



import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * ClassName: RttTest
 * Package: com.sunriz.motordrive.driver
 * Description:
 *
 * @Author BuTang
 * @Create 2024/11/25 16:17
 * @Version 1.0
 */
public class OpenocdManager {
    private static final Logger log = LoggerFactory.getLogger(OpenocdManager.class);

    // 静态变量，持有唯一的实例
    private static volatile OpenocdManager instance;

    // 私有构造函数，防止外部直接实例化
    private OpenocdManager() {
        // 可以在这里做一些初始化操作
    }

    // 提供一个公共的静态方法，获取实例
    public static OpenocdManager getInstance() {
        if (instance == null) {
            synchronized (OpenocdManager.class) {
                // 双重检查锁定，确保线程安全
                if (instance == null) {
                    instance = new OpenocdManager();
                }
            }
        }
        return instance;
    }

    private static Thread mainThread;
    private static Process process ;
    private static Thread outputThread;
    private static Thread errorThread;



    public  void start() throws InterruptedException {

        // 查询且关闭需要使用的端口
        releasePorts();
        mainThread = new Thread(() -> {
            // 构造命令
            try {
                ProcessBuilder processBuilder = new ProcessBuilder(
                        "openocd" + File.separator + "bin" + File.separator + "openocd",
                        "-f",
                        "openocd" + File.separator + "bin" + File.separator + "openocd_rtt.cfg"
                );

                // 设置工作目录
                processBuilder.directory(new File(System.getProperty("user.dir")));

                // 启动进程
                process = processBuilder.start();

                // 启动线程读取错误输出流
                errorThread = new Thread(() -> {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            if (line.contains("accepting 'rtt' connection on tcp/")){
                                log.info("8888端口连接已开启");
                            }
                            log.info(line);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                errorThread.start();

                // 等待 OpenOCD 进程结束
                int exitCode = process.waitFor();

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        mainThread.start();

    }



    public void close() {
        if (mainThread != null ) {
            try {
                // 销毁进程
                process.destroy();

                // 等待输出和错误线程结束
                if (outputThread != null && outputThread.isAlive()) {
                    outputThread.join(); // 确保线程安全退出
                }
                if (errorThread != null && errorThread.isAlive()) {
                    errorThread.join();
                }
//                if (mainThread.isAlive() ){
//                   mainThread.destroy();
//                }
                log.info("RTT 进程及其相关线程已安全停止。");

            } catch (InterruptedException e) {
                log.error("停止 RTT 线程时出错: {}" + e.getMessage());
            } finally {
                outputThread = null;
                errorThread = null;
                process = null;
                mainThread=null;
            }
        } else {
            log.info("RTT 进程未启动，无需停止。");
        }
    }


    private void releasePorts() {
        // 要释放的端口列表
        int[] ports = {8888, 6666, 4444};

        for (int port : ports) {
            try {
                // 查找占用端口的进程 ID
                log.info("Checking port {} ...",port);
                String command = "netstat -ano | findstr :" + port;
                Process findProcess = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", command});

                try (BufferedReader reader = new BufferedReader(new InputStreamReader(findProcess.getInputStream()))) {
                    String line;
                    boolean found = false;

                    while ((line = reader.readLine()) != null) {
                        // 检查是否包含 LISTENING 状态
                        if (line.contains("LISTENING")) {
                            found = true;
                            // 提取进程 ID
                            String[] parts = line.trim().split("\\s+");
                            String pid = parts[parts.length - 1];
                            log.info("Port {} is used by PID: {}",port,pid);
                            // 杀死进程（强制）
                            killProcess(pid);
                        }
                    }

                    // 如果端口没有被占用
                    if (!found) {
                        System.out.println("Port " + port + " is not in use.");
                    }
                }
            } catch (Exception e) {
                log.error("Error while checking port {} : {}" ,port,e.getMessage());
            }
        }
    }

    // 杀死指定进程的方法
    private static void killProcess(String pid) {
        try {
            String killCommand = "taskkill /PID " + pid + " /F";
            Process killProcess = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", killCommand});
            killProcess.waitFor();
            System.out.println("Process with PID " + pid + " has been terminated.");
        } catch (Exception e) {
            System.err.println("Failed to terminate process with PID " + pid + ": " + e.getMessage());
        }
    }
}
